package com.example.demo.Controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.example.common.redis.RedisCache;
import com.example.common.utils.AjaxResult;
import com.example.common.utils.TokenCookieUtil;
import com.example.demo.domain.DTO.UserLoginDTO;
import com.example.demo.domain.UserFootPrint;
import com.example.demo.domain.UserInfo;
import com.example.demo.service.GtCitysService;
import com.example.demo.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * 用户相关接口
 */
@RestController
@RequestMapping("/api/other/user")
//@RequestMapping("/user")
public class UserLoginController {

    @Autowired
    private UserInfoService userInfoService;
    //redis+type
    @Autowired

    private RedisCache redisCache;

    @Autowired
    private GtCitysService gtCitysService;

    /**
     * 注册用户
     */
    @PostMapping("/enroll")
    @ResponseBody
    public AjaxResult userEnroll(@RequestBody UserInfo userInfo) {
        //先检查这个账号是否存在
        Boolean checkUser = userInfoService.checkUser(userInfo);
        if (checkUser) {
            //如果存在
            return AjaxResult.error("注册失败", "用户已存在");
        } else {
            //注册没有UserId,指定一个唯一的UUID
            //生成UUID
            String uuid = IdUtil.fastSimpleUUID();
            userInfo.setUserid(uuid);
            //md5加密，方式不可逆
            userInfo.setPassword(DigestUtil.md5Hex(userInfo.getPassword()));
            //用户写入
            userInfoService.insertUserInfo(userInfo);
            //注册成功
            String strTest =
                    "感谢 " + userInfo.getUsername() + " 选择旅牛网" +
                            " ╭(●｀∀´●)╯╰(●’◡’●)╮";
            return AjaxResult.success("注册成功", strTest);
        }

    }

    /**
     * 生成验证码
     *
     * @param response
     * @throws IOException
     */
    @GetMapping("/code/image")
    public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //设置response响应
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(300, 100, 4, 4);
        System.out.println(shearCaptcha.getCode());
        //存客户端的请求域里面
        request.getSession().setAttribute("ShearCaptcha_CODE", shearCaptcha.getCode().toUpperCase());
        //图形验证码写出，可以写出到文件，也可以写出到流
        //输出浏览器
        OutputStream out = response.getOutputStream();
        shearCaptcha.write(out);
        out.flush();
        //关闭流
        out.close();
    }

    /**
     * 登录
     */
    @PostMapping("/login")
    @ResponseBody
    public AjaxResult login(@RequestBody UserLoginDTO userLoginDTO, HttpServletRequest request, HttpServletResponse response) {
        //验证码为空
        if (userLoginDTO.getShearCaptcha() == null) {
            return AjaxResult.error("请输入验证码");
        }
        //获取请求域的验证码信息
        String shearCaptcha_code = (String) request.getSession().getAttribute("ShearCaptcha_CODE");
        //验证码错误
        if (!userLoginDTO.getShearCaptcha().toUpperCase().equals(shearCaptcha_code)) {
            return AjaxResult.error("验证码错误");
        }
        //先检查这个账号是否存在
        Boolean checkUser = userInfoService.checkUser(userLoginDTO);
        if (!checkUser) {
            //如果存在
            return AjaxResult.error("该用户不存在，请检查账号信息");
        } else {
            //如果账号存在
            UserInfo userInfo = userInfoService.selectUserInfo(userLoginDTO.getUsername());
            //判断密码是否正确
            if (!userInfo.getPassword().equals(DigestUtil.md5Hex(userLoginDTO.getPassword()))) {
                return AjaxResult.error("密码错误");
            }
            //验证码正确，账号正确，创建token载入cookie 返回给客户端
            String token = TokenCookieUtil.createToken(userInfo);
            //将token封装进cookie
            Cookie cookie = TokenCookieUtil.takeTokenToCookie(token);
            response.addCookie(cookie);

            return AjaxResult.success("登录成功，欢迎 " + userInfo.getUsername() + "来到旅牛网", userInfo.getUsername());
        }

    }


    /**
     * 重置密码
     */
    @PostMapping("/fixp")
    @ResponseBody
    public AjaxResult againPasswd(@RequestBody UserLoginDTO userLoginDTO, HttpServletRequest request) {
        //获取请求域的验证码信息
        String shearCaptcha_code = (String) request.getSession().getAttribute("ShearCaptcha_CODE");
        System.out.println(shearCaptcha_code);
        //验证码
        String shearCaptcha = userLoginDTO.getShearCaptcha().toUpperCase();
        //验证码不正确
        if (!shearCaptcha_code.equals(shearCaptcha)) {
            return AjaxResult.error("验证码错误");
        }
        //修改密码
        boolean flag = userInfoService.updateUserInfoPassword(userLoginDTO.getUsername(), DigestUtil.md5Hex(userLoginDTO.getPassword()));
        if (flag) {
            return AjaxResult.success("密码修改成功");
        }
        //防止意外突发错误
        return AjaxResult.error("无法修改，请联系后台人员");

    }


    /**
     * 重置用户名
     */
    @PostMapping("/fixu")
    public AjaxResult againUserName(String userName, HttpServletRequest request) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(userName);
        //先检查这个账号是否存在
        Boolean checkUser = userInfoService.checkUser(userInfo);
        if (checkUser) {
            return AjaxResult.error("修改失败", "账号已存在");
        }
        //token中获取userId,判断用户是否登录
        String UserID = TokenCookieUtil.encodingToken(request.getCookies());

        if (UserID == null) {
            return AjaxResult.error("修改失败", "未有用户登录");
        }
        if (userInfoService.updateUserInfoUserName(userName, UserID)) {
            return AjaxResult.success("修改成功", userName);
        }
        //防止意外突发错误
        return AjaxResult.error("无法修改，请联系后台人员");
    }

    /**
     * 用户收藏
     */
    @GetMapping("/userCollection")
    public AjaxResult userCollection(HttpServletRequest request) {
        //token中获取userId,判断用户是否登录
        String UserID = TokenCookieUtil.encodingToken(request.getCookies());
        //如果用户未登录
        if (UserID == null) {
            return AjaxResult.error("未有用户登录");
        } else {
            //直接返回，如果要存储redis得画，一个动态数据，需要一直判断，更消耗时间和资源
            return AjaxResult.success("查询成功", userInfoService.selectUserCollectionInfo(UserID));

        }

    }


    /**
     * 添加收藏或者取消收藏某景点
     * flag 0是取消1是尝试收藏
     */
    @GetMapping("/addOrDeleteUserCollection/{spotId}")
    public AjaxResult addOrDeleteUserCollection(@PathVariable("spotId") int spotId, HttpServletRequest request) {
        //token中获取userId,判断用户是否登录

        String UserID = TokenCookieUtil.encodingToken(request.getCookies());
        //如果用户未登录
        if (UserID == null) {
            return AjaxResult.error("未有用户登录");
        }
        //是否存在
        boolean flag = userInfoService.selectSpotCollectionFlag(UserID, spotId);
        if (flag) {
            userInfoService.deleteUserCollectionInfo(UserID, spotId);
            return AjaxResult.success("取消收藏成功");
        } else {
            userInfoService.insertUserCollectionInfo(UserID, spotId);
            return AjaxResult.success("收藏成功");
        }
    }

    /**
     * 检查这个景点是否被收藏过
     */
    @GetMapping("/checkCollection/{spotId}")
    public AjaxResult checkCollection(@PathVariable("spotId") int spotId, HttpServletRequest request) {
        //token中获取userId,判断用户是否登录
        String UserID = TokenCookieUtil.encodingToken(request.getCookies());
        //如果用户未登录
        if (UserID == null) {
            return AjaxResult.error("未有用户登录");
        }
        if (userInfoService.selectSpotCollectionFlag(UserID, spotId)) {
            return AjaxResult.error("已收藏", true);
        } else {
            return AjaxResult.success("未被收藏", false);
        }
    }

    /**
     * 添加足迹
     */
    @PostMapping("/spotFootPrint/add")
    @ResponseBody
    public AjaxResult spotFootPrint(@RequestBody UserFootPrint userFootPrint, HttpServletRequest request) {
        //token中获取userId,判断用户是否登录
        String UserID = TokenCookieUtil.encodingToken(request.getCookies());
        //如果用户未登录
        if (UserID == null) {
            return AjaxResult.error("未有用户登录");
        }
        //如果用户存在需设置其用户ID
        userFootPrint.setUserId(UserID);
        //是否可以添加足迹
        boolean flag = userInfoService.selectUserFootPrint(userFootPrint);
        if (flag) {
            //添加足迹
            boolean insertFlag = userInfoService.insertUserFootPrint(userFootPrint);
            if (insertFlag) {
                return AjaxResult.success("足迹添加成功");
            } else {
                return AjaxResult.error("足迹添加失败");
            }
        } else {
            return AjaxResult.error("足迹添加失败,该足迹已存在");
        }
    }


    /**
     * 足迹列表
     */
    @GetMapping("/spotFootPrintList")
    public AjaxResult spotFootPrint(HttpServletRequest request) {
        //token中获取userId,判断用户是否登录
        String UserID = TokenCookieUtil.encodingToken(request.getCookies());
        //如果用户未登录
        if (UserID == null) {
            return AjaxResult.error("未有用户登录");
        }
        return AjaxResult.success("查询成功", userInfoService.selectUserFootPrintDto(UserID));
    }

    /**
     * 足迹省份
     */
    @GetMapping("/spotFootPrintProvinceList")
    public AjaxResult spotFootPrintProvinceList() {
        try {
            //查询redis是否存在数据
            return AjaxResult.success("查询成功", redisCache.getCacheObject("FootPrint_province"));
        } catch (NullPointerException e) {
            List<String> province = gtCitysService.selectProvince();
            //设置缓存30分钟
            redisCache.setCacheJSONObject("FootPrint_province", province, 30, TimeUnit.MINUTES);
            return AjaxResult.success("查询成功", province);
        }
    }

    /**
     * 足迹城市
     */
    @GetMapping("/spotFootPrintCityList")
    public AjaxResult spotFootPrintCityList(String province) {
        try {
            //查询redis是否存在数据
            return AjaxResult.success("查询成功", redisCache.getCacheObject("FootPrint_city_" + province));
        } catch (NullPointerException e) {
            List<String> citys = gtCitysService.selectCity(province);
            //设置缓存30分钟
            redisCache.setCacheJSONObject("FootPrint_city_" + province, citys, 30, TimeUnit.MINUTES);
            return AjaxResult.success("查询成功", citys);
        }
    }
}
